/*
 * 	S-EXPRESSIONS - Efficient representation of structured data.
 * 
 *  Copyright 2011 Jason Feingold
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at;
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.;
 */
package sexpr

import org.scalatest.FunSuite

class TestSExpr extends FunSuite
{
	var nth = 0
	// auto numbers the tests
	def atest (fn : => Unit) = { nth += 1 ; test ("test-" + nth) { fn } }
	atest
	{
		val x = SExpr read "[]"
		x match
		{
		case x : SList => assert (0 == x.items.size)
		case _ => fail ("Expected a list.")
		}
	}
	atest
	{
		val x = SExpr read "[a]"
		x match
		{
		case SList (List (SAtom (a))) =>
			expect ("a") (a)
		case _ => fail (x.toString)
		}
		expect ("[1:a]") (SExpr write x)
	}
	atest
	{
		val x = SExpr read "[a abc]"
		x match
		{
		case x : SList => 
			x.items match
			{
			case SAtom (a) :: SAtom (b) :: Nil => 
					expect ("a") (a)
					expect ("abc") (b)
			case _ => fail (x.toString)
			}
		case _ => fail (x.toString)
		}
		expect ("[1:a3:abc]") (SExpr write x)
	}
	atest
	{
		val x = SExpr read "[1:a3:abc]"
		x match
		{
		case x : SList => 
			x.items match
			{
			case SAtom (a) :: SAtom (b) :: Nil => 
					expect ("a") (a)
					expect ("abc") (b)
			case _ => fail (x.toString)
			}
		case _ => fail (x.toString)
		}
		expect ("[1:a3:abc]") (SExpr write x)
	}
	atest
	{
		val x = SExpr read "[ a[] abc]"
		x match
		{
		case x : SList => 
			x.items match
			{
			case SAtom (a) :: SList (Nil) :: SAtom (b) :: Nil => 
					expect ("a") (a)
					expect ("abc") (b)
			case _ => fail (x.toString)
			}
		case _ => fail (x.toString)
		}
		expect ("[1:a[]3:abc]") (SExpr write x)
	}
	atest
	{
		val x = SExpr read "[a []3:abc]"
		x match
		{
		case x : SList => 
			x.items match
			{
			case SAtom (a) :: SList (Nil) :: SAtom (b) :: Nil => 
					expect ("a") (a)
					expect ("abc") (b)
			case _ => fail (x.toString)
			}
		case _ => fail (x.toString)
		}
		expect ("[1:a[]3:abc]") (SExpr write x)
	}
	atest
	{
		val x = SExpr read "[a [	]  3:abc [\"4:xyz \"]]"
		x match
		{
		case x : SList => 
			x.items match
			{
			case SAtom (a) :: SList (Nil) :: SAtom (b) :: SList (SAtom (c) :: Nil) :: Nil => 
					expect ("a") (a)
					expect ("abc") (b)
					expect ("4:xyz ") (c)
			case _ => fail (x.toString)
			}
		case _ => fail (x.toString)
		}
		expect ("[1:a[]3:abc[6:4:xyz ]]") (SExpr write x)
	}
	atest
	{
		val x = SExpr read "[1:a[]3:abc[6:4:xyz ]]"
		x match
		{
		case x : SList => 
			x.items match
			{
			case SAtom (a) :: SList (Nil) :: SAtom (b) :: SList (SAtom (c) :: Nil) :: Nil => 
					expect ("a") (a)
					expect ("abc") (b)
					expect ("4:xyz ") (c)
			case _ => fail (x.toString)
			}
		case _ => fail (x.toString)
		}
		expect ("[1:a[]3:abc[6:4:xyz ]]") (SExpr write x)
	}
	atest
	{
		val x = SExpr read "[a\n \n[]3:abc]"
		x match
		{
		case x : SList => 
			x.items match
			{
			case SAtom (a) :: SList (Nil) :: SAtom (b) :: Nil => 
					expect ("a") (a)
					expect ("abc") (b)
			case _ => fail (x.toString)
			}
		case _ => fail (x.toString)
		}
		expect ("[1:a[]3:abc]") (SExpr write x)
	}
	atest
	{
		val x = SExpr read """["\x61"]"""
		expect ("[1:a]") (SExpr write x)
	}
	atest
	{
		val x = SExpr read "[a\n \n[]<3:abc>]"
		x match
		{
		case x : SList => 
			x.items match
			{
			case SAtom (a) :: SList (Nil) :: Nil => 
					expect ("a") (a)
			case _ => fail (x.toString)
			}
		case _ => fail (x.toString)
		}
		expect ("[1:a[]]") (SExpr write x)
	}
	atest
	{
		val x = SExpr read "[<a\n \n[]<3:abc>>]"
		expect (SList (Nil)) (x)
		expect ("[]") (SExpr write x)
	}
}